/**
 * 生成一个在 [0, n) 区间内非均匀分布的随机整数。
 * 通过一个偏向参数 (bias) 来控制分布，使得数值越小的整数生成的概率越高。
 *
 * @param {number} n
 *        - **说明**: 生成随机数的上限（不包含该数）。例如，如果 n = 100，则生成的随机数范围是 0 到 99。
 *        - **类型**: 整数 (Integer)
 *        - **取值建议**: 必须是一个大于 0 的正整数。如果 n <= 1，函数将始终返回 0。
 *
 * @param {number} bias
 *        - **说明**: 偏向强度参数，用于控制随机数向 0 倾斜的程度。
 *        - **类型**: 数字 (Number)
 *        - **取值建议**:
 *          - 必须是一个大于 0 的数字。
 *          - 当 `bias` > 1 时，数值越小，被选中的概率越高。这是我们想要的效果。
 *          - `bias` 的值越大，结果就越偏向于 0。
 *          - `bias` = 1 时，接近于标准的均匀分布（与 `Math.floor(Math.random() * n)` 结果类似）。
 *          - `bias` 在 (0, 1) 之间时，结果会反向偏向于 n。
 *          - **经验值**:
 *            - `2` 到 `4` 之间会产生一个比较温和但明显的偏向。
 *            - `5` 到 `10` 之间会产生非常强的偏向。
 *            - `7.21` 这个值可以用来模拟“前20%的数字占据80%的输出”这一特定场景。
 *
 * @returns {number} 返回一个在 [0, n) 区间内的随机整数。
 */
export default (n, bias = 2) => {
	// 参数校验
	if (n <= 1) {
		return 0
	}
	// 1. 获取一个 [0, 1) 之间的标准均匀分布随机数
	const rng = Math.random()

	// 2. 使用幂函数来“扭曲”这个分布。
	// 当 bias > 1 时，这个操作会把大部分结果值推向 0。
	// 3. 将 [0, 1) 范围内的偏向随机数映射到 [0, n) 的整数范围
	return Math.floor(rng ** bias * n)
}
